package com.nycreativity.elecreativity.auth;

import com.nycreativity.elecreativity.entity.dto.UserRoleDTO;
import com.nycreativity.elecreativity.util.usersession.LoginUser;
import com.nycreativity.elecreativity.util.usersession.UserContext;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.ObjectUtils;

import java.util.List;
import java.util.stream.Collectors;

/**
 * @author ttxxi
 * @description 检验授权的工具类
 * @create 2021/10/11 20:53
 */
@Slf4j
public class AuthUtil {

    /**
     * @description 判断是否有对应角色
     * @param strategy : 策略
     * @param roles : 角色数组
     * @author ttxxi
     * @create 2021/10/11 22:16
     * @return : boolean 无角色也不会报错
     */
    public static boolean haveRoles(AuthStrategy strategy, String... roles){
        //判空
        if (ObjectUtils.isEmpty(roles)){
            log.info("角色信息为空，授权失败");
            return false;
        }
        if (ObjectUtils.isEmpty(strategy)){
            log.info("策略为空，授权失败");
            return false;
        }
        //获取loginUser
        LoginUser loginUser = UserContext.get();
        if (ObjectUtils.isEmpty(loginUser)){
            log.info("当前UserContext信息为空，授权失败");
            return false;
        }
        //角色信息判断
        List<UserRoleDTO> userRoleDTOList = loginUser.getRoleList();
        if (ObjectUtils.isEmpty(userRoleDTOList)){
            log.info("用户{}未对应任何角色，授权失败", loginUser.getId());
            return false;
        }
        List<String> roleList = userRoleDTOList.stream()
                .map(UserRoleDTO::getRoleName)
                .collect(Collectors.toList());
        //根据不同策略判断
        switch (strategy){
            //全部匹配
            case ALL:{
                for (String role : roles) {
                    if (!roleList.contains(role)) {
                        log.info("用户{}没有角色{}，授权失败", loginUser.getId(), role);
                        return false;
                    }
                }
                log.info("授权成功，用户:{}, 角色:{}, 策略:{}", loginUser.getId(), roles, strategy);
                return true;
            }
            //任一匹配
            case ANY:{
                for (String role : roles) {
                    if (roleList.contains(role)) {
                        log.info("授权成功，用户:{}, 角色:{}, 策略:{}", loginUser.getId(), roles, strategy);
                        return true;
                    }
                }
                log.info("用户{}没有角色{}，授权失败", loginUser.getId(), roleList.toString());
                return false;
            }
            default:{
                log.error("策略{}错误，授权失败", strategy);
                return false;
            }
        }

    }

    /**
     * @description 判断是否有对应角色
     * @param strategy : 策略
     * @param roles : 角色数组
     * @author ttxxi
     * @create 2021/10/11 22:16
     * @return : boolean 无权限会抛异常
     */
    public static void requireRoles(AuthStrategy strategy, String... roles){
        if (!haveRoles(strategy, roles)){
            throw new RuntimeException("用户没有权限");
        }
    }

}
